#include "mockserverhandler2.h"
using namespace apollo;
using namespace apollo::core;

MockServerHandler2::MockServerHandler2(int socketDescriptor, QObject *parent) 
: QThread(parent), socketDescriptor(socketDescriptor)
{

}

MockServerHandler2::~MockServerHandler2()
{
	std::cout << "Deleting MockServerHandler" << std::endl;
	if(socket.isNull() == false && socket->isOpen())
	{
		std::cout << "Disconnect from host" << std::endl;
		socket->disconnectFromHost();
		socket->waitForDisconnected();
	}
}

void MockServerHandler2::run()
{
	//moveToThread(this);
	socket = QSharedPointer<QTcpSocket>(new QTcpSocket);
	//connect(socket.data(), SIGNAL(readyRead()), this, SLOT(read()));
	connect(socket.data(), SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error2(QAbstractSocket::SocketError)));
	if(socket->setSocketDescriptor(socketDescriptor) == false)
	{
		error2(socket->error());
		return;
	}
	if(socket->waitForConnected())
	{
		std::cout << " Created a connection with " << socket->peerAddress().toString().toStdString() << ":" << socket->peerPort() << std::endl;
		stopped = false;
	}
	else
	{
		return;
	}
	socket->write("hi", 5);
	//		socket->waitForBytesWritten();
	while(!stopped)
	{
		if(socket->isValid() == false)
		{
			emit error2(socket->error());
			break;
		}
		if(socket->bytesAvailable() == 0)
		{
			
			socket->waitForReadyRead();
		}
		else
		{
			std::cout << "received data " << std::endl;
			PayloadPtr payload(new Payload);

			WireFormat::ReadState state = format.read(socket.dynamicCast<QAbstractSocket>(), payload);

			if(state == WireFormat::Successful)
			{
				//write...
				format.write(socket.dynamicCast<QAbstractSocket>(), payload);
				socket->waitForBytesWritten();
			}
			else if(state == WireFormat::NoAvailabeBytesError)
			{
				socket->abort();
				break;
			} else if(state == WireFormat::ChecksumError)
			{
				//abort connection.
				socket->abort();
				break;
			}			

		}

	}
	std::cout << "MockServerHandler2: exist thread." << std::endl;
}

void MockServerHandler2::read()
{
	std::cout << "Triggered reading data" << std::endl;
	//mailbox.enqueue(new QEvent(QEvent::Enter));
}

void MockServerHandler2::stop()
{
	stopped = true;
	std::cout << "stop thread" << std::endl;
	//mailbox.enqueue(new QEvent(QEvent::Close));
}

void MockServerHandler2::write(char* data, int size)
{
	if(socket.isNull() == false)
	{
		if(socket->isOpen() == false)
		{
			socket->waitForConnected(10000);
		}
		if(socket->isOpen())
		{
			socket->write(data, size);
			socket->waitForBytesWritten();
		}

	}
}
void MockServerHandler2::error2(QAbstractSocket::SocketError socketError)
{
	std::cout << "MockServerHandler => error :" <<  socket ->errorString().toStdString() << " in " << socket->peerAddress().toString().toStdString() << std::endl;
	emit error(socket->peerAddress().toString(), socket->peerPort(),  socketError);
	std::cout << "stopping thread " << std::endl;
	stop();
}


